package com.autumn.util;

import com.autumn.util.tuple.TupleTwo;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Byte 帮助
 * 
 * @author 老码农
 * @date 2017年11月5日
 */
public class ByteUtils {

	/**
	 * B 的名称
	 */
	public static final String B_NAME = "B";

	/**
	 * KB 的名称
	 */
	public static final String KB_NAME = "KB";

	/**
	 * MB 的名称
	 */
	public static final String MB_NAME = "MB";

	/**
	 * MB 的名称
	 */
	public static final String GB_NAME = "GB";

	/**
	 * TB 的名称
	 */
	public static final String TB_NAME = "TB";

	/**
	 * PB 的名称
	 */
	public static final String PB_NAME = "PB";

	/**
	 * EB 的名称
	 */
	public static final String EB_NAME = "EB";

	/**
	 * KB 的字节数
	 */
	public static final long KB_SIZE = 1024;
	/**
	 * MB 的字节数
	 */
	public static final long MB_SIZE = KB_SIZE * KB_SIZE;
	/**
	 * GB 的字节数
	 */
	public static final long GB_SIZE = MB_SIZE * KB_SIZE;
	/**
	 * TB 的字节数
	 */
	public static final long TB_SIZE = GB_SIZE * KB_SIZE;
	/**
	 * PB 的字节数
	 */
	public static final long PB_SIZE = TB_SIZE * KB_SIZE;
	/**
	 * EB 的字节数
	 */
	public static final long EB_SIZE = PB_SIZE * KB_SIZE;

	/**
	 * 获取文件大小
	 * 
	 * @param value
	 *            值
	 * @return
	 */
	public static String getFileSize(Long value) {
		if (value == null || value <= 0) {
			return "0 KB";
		}
		long v = value.longValue();
		if (v < KB_SIZE) {
			return String.format("%s B", value);
		} else if (v < MB_SIZE) {
			return calcValue(v, KB_SIZE, "KB");
		} else if (v < GB_SIZE) {
			return calcValue(v, MB_SIZE, "MB");
		} else if (v < TB_SIZE) {
			return calcValue(v, GB_SIZE, "GB");
		} else if (v < EB_SIZE) {
			return calcValue(v, TB_SIZE, "PB");
		} else {
			return calcValue(v, EB_SIZE, "EB");
		}
	}

	/**
	 * 获取文件大小和单位
	 * 
	 * @param value
	 * @return
	 */
	public static TupleTwo<Double, String> getSizeAndUnit(Long value) {
		if (value == null || value <= 0) {
			return new TupleTwo<Double, String>(0.0, "KB");
		}
		long v = value.longValue();
		if (v < KB_SIZE) {
			return new TupleTwo<Double, String>((double) v, "B");
		}
		if (v < MB_SIZE) {
			return calValueAndUnit(value, KB_SIZE, "KB");
		}
		if (v < GB_SIZE) {
			return calValueAndUnit(value, MB_SIZE, "MB");
		}
		if (v < TB_SIZE) {
			return calValueAndUnit(value, GB_SIZE, "GB");
		}
		if (v < EB_SIZE) {
			return calValueAndUnit(value, TB_SIZE, "PB");
		}
		return calValueAndUnit(value, EB_SIZE, "EB");

	}

	/**
	 * @author Zhang 根据单位获取单位所对应的字节比例，比如1kb = 1024 b, 1mb = 1024 * 1024 b
	 * @param unit
	 * @return
	 */
	public static long getByteRatio(String unit) {
		unit = unit.toUpperCase().trim();
		if (unit.length() == 1 && !B_NAME.equals(unit)) {
			unit = unit + B_NAME;
		}
		switch (unit) {
		case B_NAME:
			return 1;
		case KB_NAME:
			return KB_SIZE;
		case MB_NAME:
			return MB_SIZE;
		case GB_NAME:
			return GB_SIZE;
		case TB_NAME:
			return TB_SIZE;
		case EB_NAME:
			return EB_SIZE;
		default:
			return 1;
		}
	}

	private static String calcValue(long value, long p, String unit) {
		BigDecimal decimal = new BigDecimal(String.valueOf((double) value / p));
		decimal = decimal.setScale(2, RoundingMode.HALF_EVEN);
		return String.format("%s %s", decimal, unit);
	}

	private static TupleTwo<Double, String> calValueAndUnit(long value, long p, String unit) {
		BigDecimal decimal = new BigDecimal(String.valueOf((double) value / p));
		decimal = decimal.setScale(2, RoundingMode.HALF_EVEN);
		return new TupleTwo<Double, String>(Double.valueOf(decimal.toString()), unit);
	}

	/**
	 * 是否空白字节
	 * 
	 * @param value
	 *            值
	 * @return
	 */
	public static boolean isWhiteSpace(final byte value) {
		switch (value) {
		case ' ':
		case '\n':
		case '\r':
		case '\t':
			return true;
		default:
			return false;
		}
	}

}
